linedisplaycache: improve invalidation with y_range
authorChristian Hergert <chergert@redhat.com>
Fri, 7 Aug 2020 19:25:06 +0000 (12:25 -0700)
committerChristian Hergert <chergert@redhat.com>
Fri, 7 Aug 2020 19:44:26 +0000 (12:44 -0700)
When we invalidate a y_range using the common pattern of y==0 and
old_height==new_height, we are generally invalidating the entire buffer.

This short-circuits that case to just invalidate the buffer in a faster
and more complete form. The problem here appears to be that we can't
always calculate the ranges properly to invalidate because validation
has not run far enough.

gtk/gtktextlayout.c
gtk/gtktextlinedisplaycache.c
gtk/gtktextlinedisplaycacheprivate.h

index 78439277bfb3a15492534658af522d7c7b1a4f9b..3e77b52f6c955659e5a63b99fa85fbe5af919d23 100644 (file)
@@ -656,7 +656,7 @@ gtk_text_layout_changed (GtkTextLayout *layout,
                          int            new_height)
 {
   GtkTextLayoutPrivate *priv = GTK_TEXT_LAYOUT_GET_PRIVATE (layout);
-  gtk_text_line_display_cache_invalidate_y_range (priv->cache, layout, y, old_height, FALSE);
+  gtk_text_line_display_cache_invalidate_y_range (priv->cache, layout, y, old_height, new_height, FALSE);
   gtk_text_layout_emit_changed (layout, y, old_height, new_height);
 }
 
@@ -667,7 +667,7 @@ gtk_text_layout_cursors_changed (GtkTextLayout *layout,
                                  int            new_height)
 {
   GtkTextLayoutPrivate *priv = GTK_TEXT_LAYOUT_GET_PRIVATE (layout);
-  gtk_text_line_display_cache_invalidate_y_range (priv->cache, layout, y, old_height, TRUE);
+  gtk_text_line_display_cache_invalidate_y_range (priv->cache, layout, y, old_height, new_height, TRUE);
   gtk_text_layout_emit_changed (layout, y, old_height, new_height);
 }
 
index 91ce0d98e4a565c69051cc297c25e8e30c3a24d2..27f05ad660da9c444b34ae182ce7b1b76fad5b69 100644 (file)
@@ -642,7 +642,8 @@ find_iter_at_at_y (GtkTextLineDisplayCache *cache,
  * gtk_text_line_display_cache_invalidate_y_range:
  * @cache: a GtkTextLineDisplayCache
  * @y: the starting Y position
- * @old_height: the height to invalidate
+ * @old_height: the old height of the range
+ * @new_height: the new height of the range
  * @cursors_only: if only cursors should be invalidated
  *
  * Remove all GtkTextLineDisplay that fall into the range starting
@@ -653,6 +654,7 @@ gtk_text_line_display_cache_invalidate_y_range (GtkTextLineDisplayCache *cache,
                                                 GtkTextLayout           *layout,
                                                 int                      y,
                                                 int                      old_height,
+                                                int                      new_height,
                                                 gboolean                 cursors_only)
 {
   GSequenceIter *iter;
@@ -663,7 +665,11 @@ gtk_text_line_display_cache_invalidate_y_range (GtkTextLineDisplayCache *cache,
 
   STAT_INC (cache->inval_by_y_range);
 
-  if (y < 0)
+  /* A common pattern is to invalidate the whole buffer using y==0 and
+   * old_height==new_height. So special case that instead of walking through
+   * each display item one at a time.
+   */
+  if (y < 0 || (y == 0 && old_height == new_height))
     {
       gtk_text_line_display_cache_invalidate (cache);
       return;
index ffbe67bd42436660e6f611f1b393a8ed07c55b41..31021092488778a7b616b4dffe6c9b62fa63c1aa 100644 (file)
@@ -51,7 +51,8 @@ void                     gtk_text_line_display_cache_invalidate_range   (GtkText
 void                     gtk_text_line_display_cache_invalidate_y_range (GtkTextLineDisplayCache *cache,
                                                                          GtkTextLayout           *layout,
                                                                          int                      y,
-                                                                         int                      height,
+                                                                         int                      old_height,
+                                                                         int                      new_height,
                                                                          gboolean                 cursors_only);
 void                     gtk_text_line_display_cache_set_mru_size       (GtkTextLineDisplayCache *cache,
                                                                          guint                    mru_size);